package extenstion

open class Op

class Opend : Op()


open class Oc {

    open fun Op.foo() {
        println("Op.foo in Oc")
    }

    open fun Opend.foo() {
        println("Opend.foo in Oc")
    }

    /**
     * 此处调用者类型为Op，不管传入的类型为Opend还是Op，所以只会执行Op.foo
     * 但由于Oced继承于Oc，所以当调用caller的对应类型：
     * 为Oc时，则会执行Oc下的Op.foo
     * 为Oced时，则会执行Oced下的Op.foo
     */
    fun caller(op: Op) {
        op.foo()
    }

    /**
     * 此处调用者类型为Opend，所以只会执行Opend.foo
     * 此处方法开启后，输出接口会有所变化
     */
//    fun caller(opend: Opend) {
//        opend.foo()
//    }
}

class Oced : Oc() {

    override fun Op.foo() {
        println("Op.foo in Oced")
    }

    override fun Opend.foo() {
        println("Opend.foo in Oced")
    }

}

fun main(args: Array<String>) {

    Oc().caller(Op())
    Oced().caller(Op())
    Oc().caller(Opend())
    Oced().caller(Opend())
}